<script lang="tsx">
import { defineComponent, reactive, ref } from "vue";
import { FormInst } from "naive-ui";
export default defineComponent({
  name: "BasicForm",
  props: {
    config: {
      default: {},
      type: Object,
    },
  },
  setup(props, { expose }) {
    // console.log(props.config);
    const labelWidth: number = props.config.labelWidth;
    const cols: number = props.config.cols
    const xGap: number = props.config.xGap 
    const labelPlacement: string = props.config.labelPlacement;
    const formItems: Record<string, any>[] = props.config.formItems;
    const rules: Record<string, any> = props.config.rules;
    const model = reactive<Record<string, any>>({});
    const formRef = ref<FormInst | null>(null);

    type ItemType = string | number | Array<string> | null;
    const itemInit = (item) => {
      let value: ItemType = null;
      switch (item.type) {
        case "CheckBox":
          value = [];
          break;
        case "Date":
          value = Date.now();
          break;
        case "Time":
          value = new Date().getTime();
          break;
        default:
          value = "";
      }
      model[item.field] = value;
    };
    // 表单重置
    const reset = () => {
      formItems.forEach((item) => {
        itemInit(item);
      });
    };
    // 初始化表单
    const formInit = () => {
      formItems.forEach((item) => {
        if (item.value) {
          model[item.field] = item.value;
        } else {
          itemInit(item);
        }
      });
      console.log("model", model);
    };

    formInit();

    // 渲染控件
    const renderItem = (item: Record<string, any>) => {
      switch (item.type) {
        case "Input":
          return (
            <n-input
              type={item.inputType}
              v-model:value={model[item.field]}
              placeholder={item?.placeholder}
              style={{ width: item.inputWidth }}
              show-password-on={item?.show_password_on}
              disabled={item?.disabled}
            />
          );

        case "Select":
          return (
            <n-select
              style={{ width: item.selectWidth }}
              v-model:value={model[item.field]}
              placeholder={item.placeholder}
              options={item.options}
            />
          );

        case "Switch":
          return <n-switch v-model:value={model[item.field]} placeholder={item.placeholder} />;
        case "CheckBox":
          return (
            <n-checkbox-group v-model:value={model[item.field]}>
              <n-space>
                {item.options.map((o) => {
                  return <n-checkbox value={o.value}>{o.label}</n-checkbox>;
                })}
              </n-space>
            </n-checkbox-group>
          );
        case "RadioBox":
          return (
            <n-radio-group v-model:value={model[item.field]} name={item.name}>
              <n-space>
                {item.options.map((o) => {
                  return <n-radio value={o.value}>{o.label}</n-radio>;
                })}
              </n-space>
            </n-radio-group>
          );
        case "TextArea":
          return (
            <n-input
              v-model:value={model[item.field]}
              placeholder={item.placeholder}
              type={item.inputType}
              autosize={{
                minRows: item.autosize.minRows,
                maxRows: item.autosize.maxRows,
              }}
            />
          );
        case "Date":
          return (
            <n-date-picker
              v-model:value={model[item.field]}
              type={item.inputType}
            />
          );
        case "Time":
          return <n-time-picker v-model:value={model[item.field]} />;
      }
    };

    const renderItems = (formItems: Record<string, any>[]) => {
      return formItems.map((item) => {
        return (
          <n-form-item-gi
            span={item.span}
            label={item.labelName}
            label-style={item.labelStyle}
            path={item.field}
          >
            {renderItem(item)}
          </n-form-item-gi>
        );
      });
    };
    const getFormRef = () => {
      return formRef.value;
    };
    expose({
      getFormRef,
      reset,
    });
    return () => (

      <n-form
        ref={formRef}
        model={model}
        rules={rules}
        label-placement={labelPlacement}
        require-mark-placement="right-hanging"
        label-width={labelWidth}
      >
        <n-grid cols={cols} x-gap={xGap}>
          {renderItems(formItems)}
        </n-grid>
      </n-form>

    );
  },
});
</script>

<style lang="less" scoped>

</style>
